/********************************************************************* * * Copyright (C) 2002 Andrew Khan * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ***************************************************************************/ package jxl.biff; import jxl.common.Assert; import jxl.common.Logger; /** * Contains the common data for a compound file */ public abstract class BaseCompoundFile { /** * The logger */ private static Logger logger = Logger.getLogger(BaseCompoundFile.class); /** * The identifier at the beginning of every OLE file */ protected static final byte[] IDENTIFIER = new byte[] {(byte) 0xd0, (byte) 0xcf, (byte) 0x11, (byte) 0xe0, (byte) 0xa1, (byte) 0xb1, (byte) 0x1a, (byte) 0xe1}; /** */ protected static final int NUM_BIG_BLOCK_DEPOT_BLOCKS_POS = 0x2c; /** */ protected static final int SMALL_BLOCK_DEPOT_BLOCK_POS = 0x3c; /** */ protected static final int NUM_SMALL_BLOCK_DEPOT_BLOCKS_POS = 0x40; /** */ protected static final int ROOT_START_BLOCK_POS = 0x30; /** */ protected static final int BIG_BLOCK_SIZE = 0x200; /** */ protected static final int SMALL_BLOCK_SIZE = 0x40; /** */ protected static final int EXTENSION_BLOCK_POS = 0x44; /** */ protected static final int NUM_EXTENSION_BLOCK_POS = 0x48; /** */ protected static final int PROPERTY_STORAGE_BLOCK_SIZE = 0x80; /** */ protected static final int BIG_BLOCK_DEPOT_BLOCKS_POS = 0x4c; /** */ protected static final int SMALL_BLOCK_THRESHOLD = 0x1000; // property storage offsets /** */ private static final int SIZE_OF_NAME_POS = 0x40; /** */ private static final int TYPE_POS = 0x42; /** */ private static final int COLOUR_POS = 0x43; /** */ private static final int PREVIOUS_POS = 0x44; /** */ private static final int NEXT_POS = 0x48; /** */ private static final int CHILD_POS = 0x4c; /** */ private static final int START_BLOCK_POS = 0x74; /** */ private static final int SIZE_POS = 0x78; /** * The standard property sets */ public final static String ROOT_ENTRY_NAME = "Root Entry"; public final static String WORKBOOK_NAME = "Workbook"; public final static String SUMMARY_INFORMATION_NAME = "\u0005SummaryInformation"; public final static String DOCUMENT_SUMMARY_INFORMATION_NAME = "\u0005DocumentSummaryInformation"; public final static String COMP_OBJ_NAME = "\u0001CompObj"; public final static String[] STANDARD_PROPERTY_SETS = new String[] {ROOT_ENTRY_NAME, WORKBOOK_NAME, SUMMARY_INFORMATION_NAME, DOCUMENT_SUMMARY_INFORMATION_NAME}; /** * Property storage types */ public final static int NONE_PS_TYPE = 0; public final static int DIRECTORY_PS_TYPE = 1; public final static int FILE_PS_TYPE = 2; public final static int ROOT_ENTRY_PS_TYPE = 5; /** * Inner class to represent the property storage sets. Access is public * to allow access from the PropertySetsReader demo utility */ public class PropertyStorage { /** * The name of this property set */ public String name; /** * The type of the property set */ public int type; /** * The colour of the property set */ public int colour; /** * The block number in the stream which this property sets starts at */ public int startBlock; /** * The size, in bytes, of this property set */ public int size; /** * The previous property set */ public int previous; /** * The next property set */ public int next; /** * The child for this property set */ public int child; /** * The data that created this set */ public byte[] data; /** * Constructs a property set * * @param d the bytes */ public PropertyStorage(byte[] d) { data = d; int nameSize = IntegerHelper.getInt(data[SIZE_OF_NAME_POS], data[SIZE_OF_NAME_POS + 1]); if (nameSize > SIZE_OF_NAME_POS) { logger.warn("property set name exceeds max length - truncating"); nameSize = SIZE_OF_NAME_POS; } type = data[TYPE_POS]; colour = data[COLOUR_POS]; startBlock = IntegerHelper.getInt (data[START_BLOCK_POS], data[START_BLOCK_POS + 1], data[START_BLOCK_POS + 2], data[START_BLOCK_POS + 3]); size = IntegerHelper.getInt (data[SIZE_POS], data[SIZE_POS + 1], data[SIZE_POS + 2], data[SIZE_POS + 3]); previous = IntegerHelper.getInt (data[PREVIOUS_POS], data[PREVIOUS_POS+1], data[PREVIOUS_POS+2], data[PREVIOUS_POS+3]); next = IntegerHelper.getInt (data[NEXT_POS], data[NEXT_POS+1], data[NEXT_POS+2], data[NEXT_POS+3]); child = IntegerHelper.getInt (data[CHILD_POS], data[CHILD_POS+1], data[CHILD_POS+2], data[CHILD_POS+3]); int chars = 0; if (nameSize > 2) { chars = (nameSize - 1) / 2; } StringBuffer n = new StringBuffer(""); for (int i = 0; i < chars ; i++) { n.append( (char) data[i * 2]); } name = n.toString(); } /** * Constructs an empty property set. Used when writing the file * * @param name the property storage name */ public PropertyStorage(String name) { data = new byte[PROPERTY_STORAGE_BLOCK_SIZE]; Assert.verify(name.length() < 32); IntegerHelper.getTwoBytes((name.length() + 1) * 2, data, SIZE_OF_NAME_POS); // add one to the name length to allow for the null character at // the end for (int i = 0; i < name.length(); i++) { data[i * 2] = (byte) name.charAt(i); } } /** * Sets the type * * @param t the type */ public void setType(int t) { type = t; data[TYPE_POS] = (byte) t; } /** * Sets the number of the start block * * @param sb the number of the start block */ public void setStartBlock(int sb) { startBlock = sb; IntegerHelper.getFourBytes(sb, data, START_BLOCK_POS); } /** * Sets the size of the file * * @param s the size */ public void setSize(int s) { size = s; IntegerHelper.getFourBytes(s, data, SIZE_POS); } /** * Sets the previous block * * @param prev the previous block */ public void setPrevious(int prev) { previous = prev; IntegerHelper.getFourBytes(prev, data, PREVIOUS_POS); } /** * Sets the next block * * @param nxt the next block */ public void setNext(int nxt) { next = nxt; IntegerHelper.getFourBytes(next, data, NEXT_POS); } /** * Sets the child * * @param dir the child */ public void setChild(int dir) { child = dir; IntegerHelper.getFourBytes(child, data, CHILD_POS); } /** * Sets the colour * * @param col colour */ public void setColour(int col) { colour = col == 0 ? 0 : 1; data[COLOUR_POS] = (byte) colour; } } /** * Constructor */ protected BaseCompoundFile() { } }